package cn.tedu.travelsystem.user.controller;

import cn.tedu.travelsystem.base.exception.AccessLimitException;
import cn.tedu.travelsystem.base.filter.SensitiveWordFilter;
import cn.tedu.travelsystem.base.response.JsonResult;
import cn.tedu.travelsystem.base.response.StatusCode;
import cn.tedu.travelsystem.base.utils.AccessLimitUtil;
import cn.tedu.travelsystem.base.utils.IpUtil;
import cn.tedu.travelsystem.base.utils.JwtUtil;
import cn.tedu.travelsystem.user.mapper.UserMapper;
import cn.tedu.travelsystem.user.pojo.dto.UserLoginParm;
import cn.tedu.travelsystem.user.pojo.dto.UserRegParm;
import cn.tedu.travelsystem.user.pojo.dto.UserUpdateDTO;
import cn.tedu.travelsystem.user.pojo.entity.User;
import cn.tedu.travelsystem.user.pojo.vo.UserVO;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.Date; // 导入 java.util.Date 类
import java.util.UUID;


@Slf4j
@RestController
@RequestMapping("/user")
@Api(tags = "06.用户模块")
public class UserController {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private AccessLimitUtil accessLimitUtil;
    @Qualifier("redisTemplate")
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SensitiveWordFilter sensitiveWordFilter;

    @PostMapping("reg")
    @ApiOperation("用户注册")
    @ApiOperationSupport(order = 10)
    public JsonResult reg(@Validated @RequestBody UserRegParm userRegParam) {
        String username = userRegParam.getUsername();

        // 1. 非空（去除前后空格后判断）
        if (username == null || username.trim().isEmpty()) {
            return JsonResult.fail("用户名不能为空或全是空格");
        }

        // 2. 不能以空格开头
        if (Character.isWhitespace(username.charAt(0))) {
            return JsonResult.fail("用户名不能以空格开头");
        }

        // 3. 敏感词检测
        if (sensitiveWordFilter.containsSensitiveWord(username)) {
            String word = sensitiveWordFilter.getMatchedWord(username).orElse("未知词");
            return JsonResult.fail("用户名包含敏感词：【" + word + "】，请修改后再试！");
        }

        // 4. 重复用户名校验
        int i = userMapper.selectByUsername(username);
        if (i > 0) {
            return JsonResult.fail("用户名已存在，请更换");
        }

        // 5. 保存用户
        User user = new User();
        BeanUtils.copyProperties(userRegParam, user);
        user.setLast_login_time(new Date());
        userMapper.insertUser(user);

        return JsonResult.ok();
    }

    @ApiOperation("用户登录功能")
    @ApiOperationSupport(order = 20)
    @PostMapping("login")
    public JsonResult login(@RequestBody UserLoginParm userLoginParam,
                            @ApiIgnore HttpSession session,
                            HttpServletRequest request) {

        String ip = IpUtil.getRealIp(request);
        String key = "login_fail:" + ip;  // 用于失败次数的记录
        String successKey = "login_success:" + userLoginParam.getUsername();  // 用于成功登录次数的记录

        // 检查登录失败次数
        if (accessLimitUtil.isFrequent(key, 5, 60)) {  // 如果连续 5 次失败
            long remaining = accessLimitUtil.getRemainingTime(key); // 获取剩余时间
            throw new AccessLimitException("登录失败次数过多，请 " + remaining + " 秒后再试");
        }

        // 查用户
        UserVO userVO = userMapper.selectByUsernameAndPassword(userLoginParam);
        if (userVO == null) {
            // 用户不存在
            accessLimitUtil.isFrequent(key, 5, 60);  // 失败才计数
            return new JsonResult(StatusCode.USER_NOT_EXIST);  // 返回"用户不存在"的状态码
        }

        // 验证密码（根据需求，可能是加密后的对比）
        if (!userVO.getPassword().equals(userLoginParam.getPassword())) {
            // 密码错误
            accessLimitUtil.isFrequent(key, 5, 60);  // 密码错误才计数
            return new JsonResult(StatusCode.USERNAME_PASSWORD_ERROR);  // 返回"密码错误"的状态码
        }

        // 检查用户是否频繁登录
        if (accessLimitUtil.isFrequent(successKey, 10, 60)) {  // 10 次成功登录限制
            long remaining = accessLimitUtil.getRemainingTime(successKey); // 获取剩余时间
            throw new AccessLimitException("登录次数过多，请 " + remaining + " 秒后再试");
        }

        // 登录成功：清除失败次数记录
        redisTemplate.delete(key);  // 清除失败次数的记录
        // 计数成功登录次数
        accessLimitUtil.isFrequent(successKey, 10, 60);  // 成功登录计数

        // 返回 token
        session.setAttribute("user", userVO);
        String token = JwtUtil.generateToken(userVO.getUsername(), Collections.singletonMap("username", userVO.getUsername()));
        userVO.setToken(token);
        return JsonResult.ok(userVO);
    }



    @ApiOperation("用户状态检测功能")
    @GetMapping("currentUser")
    @ApiOperationSupport(order = 30)
    public JsonResult currentUser(@RequestHeader("Authorization") String authHeader) {
        String token = authHeader.replace("Bearer ", "");
        if (!JwtUtil.validateToken(token)) {
            return new JsonResult(StatusCode.NOT_LOGIN);
        }
        String username = JwtUtil.getUsernameFromToken(token);
        UserVO userVO = userMapper.selectUserByUsername(username);
        return JsonResult.ok(userVO);
    }
//    public JsonResult currentUser(HttpSession session){
//        log.debug("session ="+session);
//        UserVO userVO = (UserVO) session.getAttribute("user");
//        if (userVO == null) {
//            return new JsonResult(StatusCode.NOT_LOGIN); // 返回未登录状态码
//        }
//        return JsonResult.ok(userVO);
//    }

    @ApiOperation("用户退出登录功能")
    @GetMapping("logout")
    public JsonResult logout(HttpSession session){
        session.removeAttribute("user");
        return JsonResult.ok();
    }

    @ApiOperationSupport(order = 40)
    @ApiOperation("删除用户功能")
    @DeleteMapping("delete/{user_id}") // 改成路径参数
    @ResponseBody
    public String delete(@PathVariable Long user_id) {
        System.out.println(user_id);
        int rows = userMapper.deleteUser(user_id); // 执行删除并返回影响行数
        if (rows > 0) {
            return "删除成功";
        } else {
            return "删除失败，用户不存在或已被删除";
        }
    }

    @PutMapping("update")
    @ApiOperation("更新用户信息")
    @ApiOperationSupport(order = 50)
    public JsonResult update(
            @Validated @RequestBody UserUpdateDTO userUpdateDTO,
            @RequestHeader("Authorization") String authHeader) {
        // 验证并解析Token
        String token = authHeader.replace("Bearer ", "");
        if (!JwtUtil.validateToken(token)) {
            return new JsonResult(StatusCode.NOT_LOGIN);
        }
        String username = JwtUtil.getUsernameFromToken(token);
        // 根据用户名查询用户信息
        UserVO userVO = userMapper.selectUserByUsername(username);
        if (userVO == null) {
            return new JsonResult(StatusCode.USER_NOT_EXIST);
        }
        // 更新用户信息
        User user = new User();
        BeanUtils.copyProperties(userUpdateDTO, user);
        user.setUser_id(userVO.getUser_id());
        userMapper.updateUser(user);
        // 返回最新信息
        UserVO updatedUser = userMapper.selectByUserId(user.getUser_id());
        return JsonResult.ok(updatedUser);
    }

    @PostMapping("avatar")
    @ApiOperation("上传头像")
    @ApiOperationSupport(order = 60)
    public JsonResult uploadAvatar(
            @RequestParam("file") MultipartFile file,
            @RequestHeader("Authorization") String authHeader) throws IOException {
        // 从Token解析用户名
        String token = authHeader.replace("Bearer ", "");
        if (!JwtUtil.validateToken(token)) {
            return new JsonResult(StatusCode.USER_NOT_EXIST);
        }
        String username = JwtUtil.getUsernameFromToken(token);
        UserVO userVO = userMapper.selectUserByUsername(username);
        if (userVO == null) {
            return new JsonResult(StatusCode.VALIDATE_ERROR);
        }


        // 修改路径处理为绝对路径
        String uploadDir = "uploads";
        Path dirPath = Paths.get(uploadDir).toAbsolutePath().normalize();
        Files.createDirectories(dirPath); // 确保目录存在
        String fileName = UUID.randomUUID() + "-" + file.getOriginalFilename();
        Path filePath = dirPath.resolve(fileName);

        try {
            file.transferTo(filePath.toFile());
            log.info("文件保存成功，路径：{}", filePath);
        } catch (IOException e) {
            log.error("文件保存失败：", e);
            return new JsonResult(StatusCode.UPLOAD_FAILED);
        }

//        // 处理文件上传
//        String fileName = UUID.randomUUID() + "-" + file.getOriginalFilename();
//        Path path = Paths.get("uploads", fileName);
//        Files.createDirectories(path.getParent());
//        file.transferTo(path.toFile());

        // 更新数据库
        userMapper.updateAvatar(userVO.getUser_id(), fileName);

        return JsonResult.ok(fileName);
    }


}